﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DataAbstractor;
using NUnit.Framework;

namespace DataAbstractorTest
{
    public class DataAbstractorInitialise : IDataAbstractorMapping
    {
        public void InitialiseMapping()
        {
            DataAbstractor.DataAbstractor.Map<DataAbstractorTest.TestDestinationC, DataAbstractorTest.TestSourceC>()
                .From(i => i.A).To(i => i.D);
        }
    }

    [TestFixture]
    public class DataAbstractorTest
    {
        public class TestDestinationA
        {
            public int A { get; set; }
            public string B { get; set; }
        }

        public class TestSourceA
        {
            public string B { get; set; }
        }

        public class TestDestinationB
        {
            public int A { get; set; }
            public string B { get; set; }
        }

        public class TestSourceB
        {
            public string B { get; set; }
        }

        public class TestDestinationC
        {
            public int A { get; set; }
            public string B { get; set; }
            public int C { get; set; }
        }

        public class TestSourceC
        {
            public string B { get; set; }
            public int D { get; set; }
        }

        [Test]
        public void TestAllPropertiesMapped()
        {
            DataAbstractor.DataAbstractor.AllPropertiesMustBeMapped = false;
            var source = new TestSourceA { B = "hi" };
            var result = source.To<TestDestinationA>();
            Assert.AreEqual(source.B, result.B);
            Assert.AreEqual(0, result.A);
            DataAbstractor.DataAbstractor.AllPropertiesMustBeMapped = true;
            Assert.Throws<MapException>(() =>
                {
                    source.To<TestDestinationA>();
                });
            DataAbstractor.DataAbstractor.Map<TestDestinationA, TestSourceA>()
                .Ignore(i => i.A);
            var result2 = source.To<TestDestinationA>();
            Assert.AreEqual(source.B, result2.B);
            Assert.AreEqual(0, result2.A);
            DataAbstractor.DataAbstractor.AllPropertiesMustBeMapped = false;
        }

        [Test]
        public void EnforcePreMapping()
        {
            DataAbstractor.DataAbstractor.EnforcePreMapping = false;
            var source = new TestSourceB { B = "hi" };
            var result = source.To<TestDestinationB>();
            Assert.AreEqual(source.B, result.B);
            Assert.AreEqual(0, result.A);
            DataAbstractor.DataAbstractor.EnforcePreMapping = true;
            var source2 = new TestSourceC { B = "hi", D = -99 };
            Assert.Throws<MapException>(() =>
                {
                    source.To<TestDestinationC>();
                });
            DataAbstractor.DataAbstractor.Initialise();
            var result2 = source2.To<TestDestinationC>();
            Assert.AreEqual(source2.B, result2.B);
            Assert.AreEqual(source2.D, result2.A);
            DataAbstractor.DataAbstractor.EnforcePreMapping = false;
        }
    }
}
